﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using YanZhiwei.DotNet3._5.Utilities.Enums;
using YanZhiwei.DotNet3._5.Utilities.Models;

namespace YanZhiwei.DotNet3._5.Utilities.Common
{
    using YDonet2 = YanZhiwei.DotNet2.Utilities.Common;
    /// <summary>
    /// 获取系统硬件、软件信息
    /// </summary>
    public static class SystemInfoHelper
    {
        #region 获取指定WMI路径的信息集合
        /// <summary>
        /// 获取指定WMI路径的信息集合
        /// </summary>
        public static IEnumerable<Dictionary<string, object>> GetWmiInfos(WMIPath wmi)
        {
            ManagementClass _mc = new ManagementClass(wmi.ToString());
            ManagementObjectCollection _moc = _mc.GetInstances();
            return (from ManagementBaseObject mo in _moc
                    select mo.Properties.Cast<PropertyData>()
                        .ToDictionary(property => property.Name, property => property.Value))
                .ToList();
        }
        #endregion 
        #region 获取硬件信息标识
        /// <summary>
        /// 获取硬件信息标识
        /// </summary>
        public static string GetHardwareId()
        {
            var _cpuId = new ManagementClass(WMIPath.Win32_Processor.ToString()).GetInstances()
                .Cast<ManagementObject>().Select(cpu => cpu.Properties["ProcessorId"].Value).First();
            var _boardId = new ManagementClass(WMIPath.Win32_BaseBoard.ToString()).GetInstances()
                .Cast<ManagementObject>().Select(disk => disk.Properties["SerialNumber"].Value).First();
            var _diskId = new ManagementClass(WMIPath.Win32_DiskDrive.ToString()).GetInstances()
                .Cast<ManagementObject>().Select(disk => disk.Properties["SerialNumber"].Value).First();
            string _value = string.Format("{0}{1}{2}", _cpuId, _boardId, _diskId);//"{0}{1}{2}".FormatWith(cpuId, boardId, diskId);
            return GetHardwareId(_value);
        }
        #endregion 
        #region 由指定字符串生成硬件信息标识
        /// <summary>
        /// 由指定字符串生成硬件信息标识
        /// </summary>
        public static string GetHardwareId(string value)
        {
            value = YDonet2.StringHelper.ToMD5(value).Substring(0, 20).ToUpper();
            value = YDonet2.StringHelper.Reverse(value);
            string[] _strs = new string[5];
            for (int i = 0; i < 5; i++)
            {
                _strs[i] = value.Substring(i * 4, 4);
            }
            return _strs.ExpandAndToString("-");
        }
        #endregion 
        #region 获取操作系统名称
        /// <summary>
        /// 获取操作系统名称
        /// </summary>
        public static string GetOperationSystemName()
        {
            return new ManagementClass(WMIPath.Win32_OperatingSystem.ToString()).GetInstances()
                .Cast<ManagementObject>().Select(op => op.Properties["Name"].Value).First().ToString();
        }
        #endregion 
        #region 获取系统信息
        /// <summary>
        /// 获取系统信息
        /// </summary>
        public static SystemInfo GetSystemInfo()
        {
            SystemInfo _info = new SystemInfo();
            //CPU
            var _objects = new ManagementClass(WMIPath.Win32_Processor.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            _info.CpuName = _objects.Select(m => (string)m.Properties["Name"].Value).FirstOrDefault();
            _info.CpuId = _objects.Select(m => (string)m.Properties["ProcessorId"].Value).FirstOrDefault();

            //主板
            _objects = new ManagementClass(WMIPath.Win32_BaseBoard.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            _info.BoardName = _objects.Select(m => (string)m.Properties["Manufacturer"].Value + " " +
                                                 (string)m.Properties["Product"].Value + " " +
                                                 (string)m.Properties["Version"].Value).FirstOrDefault();
            _info.BoardId = _objects.Select(m => (string)m.Properties["SerialNumber"].Value).FirstOrDefault();

            //硬盘
            _objects = new ManagementClass(WMIPath.Win32_DiskDrive.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            _info.DiskName = _objects.Select(m => (string)m.Properties["Model"].Value + " " +
                                                (Convert.ToDouble(m.Properties["Size"].Value) / (1024 * 1024 * 1024)) + " GB").FirstOrDefault();
            _info.DiskId = _objects.Select(m => (string)m.Properties["SerialNumber"].Value).FirstOrDefault();

            //操作系统
            _objects = new ManagementClass(WMIPath.Win32_OperatingSystem.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            _info.OSName = _objects.Select(m => (string)m.Properties["Caption"].Value).FirstOrDefault();
            _info.OSCsdVersion = _objects.Select(m => (string)m.Properties["CSDVersion"].Value).FirstOrDefault();
            _info.OSIs64Bit = _objects.Select(m => (string)m.Properties["OSArchitecture"].Value == "64-bit").FirstOrDefault();
            _info.OSVersion = _objects.Select(m => (string)m.Properties["Version"].Value).FirstOrDefault();
            _info.OSPath = _objects.Select(m => (string)m.Properties["WindowsDirectory"].Value).FirstOrDefault();

            //内存
            _info.PhysicalMemoryFree = _objects.Select(m => Convert.ToDouble(m.Properties["FreePhysicalMemory"].Value) / (1024)).FirstOrDefault();
            _info.PhysicalMemoryTotal = _objects.Select(m => Convert.ToDouble(m.Properties["TotalVisibleMemorySize"].Value) / (1024)).FirstOrDefault();

            //屏幕
            _objects = new ManagementClass(WMIPath.Win32_VideoController.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            _info.ScreenWith = _objects.Select(m => Convert.ToInt32(m.Properties["CurrentHorizontalResolution"].Value)).FirstOrDefault();
            _info.ScreenHeight = _objects.Select(m => Convert.ToInt32(m.Properties["CurrentVerticalResolution"].Value)).FirstOrDefault();
            _info.ScreenColorDepth = _objects.Select(m => Convert.ToInt32(m.Properties["CurrentBitsPerPixel"].Value)).FirstOrDefault();
            return _info;
        }
        #endregion 
        #region 获取当前系统运行的进程列表
        /// <summary>
        /// 获取当前系统运行的进程列表
        /// </summary>
        public static IEnumerable<string> GetProcessNames()
        {
            var _objects = new ManagementClass(WMIPath.Win32_Process.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            return _objects.Select(m => (string)m.Properties["Caption"].Value).OrderBy(m => m);
        }
        #endregion 
        #region 获取当前系统正在运行的服务列表
        /// <summary>
        /// 获取当前系统正在运行的服务列表
        /// </summary>
        public static IEnumerable<string> GetStartedServiceNamesEnumerable()
        {
            var _objects = new ManagementClass(WMIPath.Win32_Service.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            return _objects.Where(m => (bool)m.Properties["Started"].Value)
                .Select(m => (string)m.Properties["Caption"].Value).OrderBy(m => m);
        }
        #endregion 
        #region 获取剩余空间最大的逻辑磁盘名称
        /// <summary>
        /// 获取剩余空间最大的逻辑磁盘名称
        /// </summary>
        public static string GetMaxFreeSizeLogicalDisk()
        {
            var _objects = new ManagementClass(WMIPath.Win32_LogicalDisk.ToString()).GetInstances().Cast<ManagementObject>().ToArray();
            return _objects.OrderByDescending(m => Convert.ToInt64(m.Properties["FreeSpace"].Value))
                .Select(m => (string)m.Properties["Caption"].Value)
                .FirstOrDefault();
        }
        #endregion 
    }
}
